﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Skynet.BusinessEntities;

namespace Skynet.BusinessLogic.DataAccess
{
    public class AlternativeRepository : DataAccess.MasterDAABRepository<BusinessEntities.BaseAlternative>, IAlternativeRepository
    {
        public AlternativeRepository(IUnityContainer container)
            : base(container)
        { 

        }


        private List<BusinessEntities.BoolAlternative> CustomerBoolAlternatives(Guid CustomerQuestionId)
        {
            var result = new List<BusinessEntities.BoolAlternative>();
            var cmdCustomerAlternatives = this.SkynetLibraryDatabase.GetSqlStringCommand("select BAC.Id, BAC.AlternativeId, BA.QuestionId, BAC.Answer as CustomerAnswer, BA.Answer, BA.Data, BA.Score from BoolAlternativesByCustomer BAC join BoolAlternatives BA on BAC.AlternativeId= BA.Id where BAC.CustomerQuestionId = @CustomerQuestionId order by BAC.CustomerQuestionId, BA.Data desc");
            this.SkynetLibraryDatabase.AddInParameter(cmdCustomerAlternatives, "CustomerQuestionId", System.Data.DbType.Guid, CustomerQuestionId);
            var CustomerAlternativesReader = this.SkynetLibraryDatabase.ExecuteReader(cmdCustomerAlternatives);
            while (CustomerAlternativesReader.Read())
            {
                var alternative = new BusinessEntities.BoolAlternative();
                alternative.Id = (Guid)CustomerAlternativesReader["AlternativeId"];
                alternative.CustomerAlternativeId = (Guid)CustomerAlternativesReader["Id"];
                alternative.CustomerQuestionId = CustomerQuestionId;
                alternative.Answer = (bool)CustomerAlternativesReader["Answer"];
                alternative.Data = (bool)CustomerAlternativesReader["Data"];
                alternative.Score = (double)CustomerAlternativesReader["Score"];
                alternative.QuestionId = (Guid)CustomerAlternativesReader["QuestionId"];
                int customerAnswerIndex = CustomerAlternativesReader.GetOrdinal("CustomerAnswer");
                if (!CustomerAlternativesReader.IsDBNull(customerAnswerIndex))
                    alternative.CustomerAnswer = (bool?)CustomerAlternativesReader.GetBoolean(customerAnswerIndex);                
                result.Add(alternative);
            }
            return result;            
        }

 
        private List<BusinessEntities.BoolAlternative> DesignBoolAlternativesByQuestionId(Guid QuestionId)
        {
            var  result = new List<BusinessEntities.BoolAlternative>();
            var cmd = this.SkynetLibraryDatabase.GetSqlStringCommand("select * from [BoolAlternatives] where QuestionId=@QuestionId order by id");
            this.SkynetLibraryDatabase.AddInParameter(cmd, "QuestionId", System.Data.DbType.Guid, QuestionId);
            var reader = this.SkynetLibraryDatabase.ExecuteReader(cmd);
            var mapper = MapBuilder<BusinessEntities.BoolAlternative>.MapNoProperties().MapByName(c => c.Id).MapByName(c => c.QuestionId).MapByName(c => c.Score).MapByName(c => c.Answer).MapByName(c => c.Data).Build();
            while (reader.Read())
            {
                result.Add(mapper.MapRow(reader));
            }
            return result;          
        }

        private BusinessEntities.BoolAlternative DesignBoolAlternative(Guid AlternativeId)
        {
            BoolAlternative result = null;
            var cmd = this.SkynetLibraryDatabase.GetSqlStringCommand("select * from [BoolAlternatives] where Id=@AlternativeId order by id");
            this.SkynetLibraryDatabase.AddInParameter(cmd, "AlternativeId", System.Data.DbType.Guid, AlternativeId);
            var reader = this.SkynetLibraryDatabase.ExecuteReader(cmd);
            var mapper = MapBuilder<BusinessEntities.BoolAlternative>.MapNoProperties().MapByName(c => c.Id).MapByName(c => c.QuestionId).MapByName(c => c.Score).MapByName(c => c.Answer).MapByName(c => c.Data).Build();
            if(reader.Read())
            {
                result = mapper.MapRow(reader);
            }
            return result;
        }

        public BusinessEntities.BaseAlternative DesignAlternative(Guid AlternativeId)
        {
            var result = this.DesignBoolAlternative(AlternativeId);
            return result;
        }
        public LinkedList<BusinessEntities.BaseAlternative> DesignAlternativesByQuestionId(Guid QuestionId)
        {
            var result = new LinkedList<BusinessEntities.BaseAlternative>();
            var yna = this.DesignBoolAlternativesByQuestionId(QuestionId);            
            foreach (var item in yna)
            {
                result.AddLast(item);                
            }
            return result;
        }
        public LinkedList<BusinessEntities.BaseAlternative> RuntimeAlternativesByQuestionId(Guid CustomerQuestionId)
        {
            var result = new LinkedList<BusinessEntities.BaseAlternative>();
            var bresult = this.CustomerBoolAlternatives(CustomerQuestionId);
            foreach (var item in bresult)
            {
                result.AddLast(item);
            }
            return result;
        }
        public override void Add(BusinessEntities.BaseAlternative alt)
        {
            if (alt is BusinessEntities.BoolAlternative)
            {
                var target = alt as BusinessEntities.BoolAlternative;
                var cmd = this.SkynetLibraryDatabase.GetSqlStringCommand("insert into [BoolAlternatives] values(@Id, @QuestionId,@Data,@Answer,@Score)");
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Id", System.Data.DbType.Guid, alt.Id);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "QuestionId", System.Data.DbType.Guid, alt.QuestionId);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Data", System.Data.DbType.Boolean, target.Data);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Answer", System.Data.DbType.Boolean, target.Answer);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Score", System.Data.DbType.Double, target.Score);
                this.SkynetLibraryDatabase.ExecuteNonQuery(cmd);
            }
        }
        public void Update(BusinessEntities.BaseAlternative alt)
        {
            if (alt is BusinessEntities.BoolAlternative)
            {
                var target = alt as BusinessEntities.BoolAlternative;
                var cmd = this.SkynetLibraryDatabase.GetSqlStringCommand("update BoolAlternatives set Data=@Data, Answer=@Answer, Score=@Score where Id=@Id");
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Data", System.Data.DbType.Boolean, target.Data);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Answer", System.Data.DbType.Boolean, target.Answer);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Score", System.Data.DbType.Double, target.Score);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Id", System.Data.DbType.Guid, alt.Id);
                this.SkynetLibraryDatabase.ExecuteNonQuery(cmd);
            }
        }
        public void AddRuntimeAlternative(BusinessEntities.BaseAlternative alt)
        {   
            if (alt is BusinessEntities.BoolAlternative)
            {
                var target = alt as BusinessEntities.BoolAlternative;
                var cmd = this.SkynetLibraryDatabase.GetSqlStringCommand("insert into [BoolAlternativesByCustomer] values(@Id, @CustomerQuestionId,@AlternativeId,@Created,@Updated,@Answer)");
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Id", System.Data.DbType.Guid, alt.CustomerAlternativeId);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "CustomerQuestionId", System.Data.DbType.Guid, alt.CustomerQuestionId);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "AlternativeId", System.Data.DbType.Guid, target.Id);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Created", System.Data.DbType.DateTime, DateTime.Now);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Updated", System.Data.DbType.DateTime, DateTime.Now);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Answer", System.Data.DbType.Boolean, target.CustomerAnswer);
                this.SkynetLibraryDatabase.ExecuteNonQuery(cmd);                                       
            }                            
        }
        


        public void LoadCustomerAnswer(ref BusinessEntities.BaseAlternative alt)
        {
            if (alt is BusinessEntities.BoolAlternative)
            {
                var target = alt as BusinessEntities.BoolAlternative;
                var cmd = this.SkynetLibraryDatabase.GetSqlStringCommand("select Answer from BoolAlternativesByCustomer where Id=@Id");
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Id", System.Data.DbType.Guid, alt.CustomerAlternativeId);
                using (var reader = this.SkynetLibraryDatabase.ExecuteReader(cmd))
                {
                    if (reader.Read())
                    {
                        var index = reader.GetOrdinal("Answer");
                        if (!reader.IsDBNull(index))
                            target.Answer = reader.GetBoolean(index);
                    }    
                }                
            }
        }
        public void LoadDesignAlternative(ref BusinessEntities.BaseAlternative alt)
        {
            if (alt is BusinessEntities.BoolAlternative)
            {
                var target = alt as BusinessEntities.BoolAlternative;
                var cmd = this.SkynetLibraryDatabase.GetSqlStringCommand("select BA.QuestionId, BA.Data from BoolAlternatives BA join BoolAlternativesByCustomer BAC on BA.Id = AlternativeId where BAC.Id=@Id");
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Id", System.Data.DbType.Guid, alt.CustomerAlternativeId);
                using (var reader = this.SkynetLibraryDatabase.ExecuteReader(cmd))
                {
                    if (reader.Read())
                    {
                        target.QuestionId = (Guid)reader["QuestionId"];
                        var index = reader.GetOrdinal("Data");
                        if (!reader.IsDBNull(index))
                            target.Data = reader.GetBoolean(index);                        
                    }
                }      
            }
        }
        public void UpdateCustomerAnswer(BaseAlternative alt)
        {
            if (alt is BusinessEntities.BoolAlternative)
            {
                var target = alt as BusinessEntities.BoolAlternative;
                var cmd = this.SkynetLibraryDatabase.GetSqlStringCommand("update BoolAlternativesByCustomer set Answer = @Answer where Id=@Id");
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Answer", System.Data.DbType.Boolean, target.CustomerAnswer);
                this.SkynetLibraryDatabase.AddInParameter(cmd, "Id", System.Data.DbType.Guid, target.CustomerAlternativeId);
                this.SkynetLibraryDatabase.ExecuteNonQuery(cmd);
            }
        }
        public LinkedList<BusinessEntities.BaseAlternative> CalificationAlternativesByCustomerQuestionId(Guid CustomerQuestionId)
        {
            var result = new LinkedList<BusinessEntities.BaseAlternative>();
            var ba = this.CustomerBoolAlternatives(CustomerQuestionId);
            foreach (var item in ba)
            {
                result.AddLast(item);                
            }
            return result;
        }

    }
}